package cz.semjob.document.processing.batch;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cz.semjob.document.AnnotatedDocument;
import cz.semjob.document.annotation.DocumentAnnotations;
import cz.semjob.document.annotation.reader.AnnotationReader;
import cz.semjob.document.annotation.reader.AnnotationReaderException;
import cz.semjob.document.processing.DocumentInstance;
import cz.semjob.document.processing.DocumentProcessingException;
import cz.semjob.document.processing.reader.DocumentInstanceReader;
import cz.semjob.linguistic.reader.CoNNLXReader;

@Component
public class DocumentsBatchProcessor {
	
	private static Logger logger = Logger.getLogger(DocumentsBatchProcessor.class);
	
	@Autowired
	private CoNNLXReader linguisticReader; 
	
	@Autowired
	private DocumentInstanceReader dir; 
	
	@Autowired
	private AnnotationReader annotationReader;
	
	FilenameFilter txtFilter = new FilenameFilter() {
		
		public boolean accept(File dir, String name) {
			if (name.toLowerCase().endsWith(".txt")){
				return true;
			}
			return false;
		}
	};
	
	public List<DocumentInstance> processDocumentInstancesBatch(String inputDirectoryPath, String processedDirectoryPath) throws DocumentProcessingException {
		File inputDirectory = new File(inputDirectoryPath);
		if (!inputDirectory.isDirectory()) {
			throw new DocumentProcessingException("Input directory is not a directory: " + inputDirectoryPath);
		}
		File processedDirectory = new File(processedDirectoryPath);
		if (!processedDirectory.isDirectory()) {
			throw new DocumentProcessingException("Processed directory is not a directory: " + processedDirectoryPath);
		}
		
		List<DocumentInstance> documents = new ArrayList<DocumentInstance>();
		for(String inputTextFilePath : inputDirectory.list(txtFilter)) {
			File inputTextFile = new File(inputDirectory, inputTextFilePath);
			String conllxFileName = inputTextFile.getName().substring(0, inputTextFile.getName().length()-4) + ".conllx";
			File conllxFile = new File(processedDirectory, conllxFileName);
			if (!conllxFile.isFile()) {
				logger.warn("Could not find conllx file for file '" + conllxFile.getPath() + "', skipping.");
				continue;
			}
			DocumentInstance document;
			try {
				document = dir.readDocumentInstance(inputTextFile, conllxFile);
			} catch (IOException e) {
				logger.error(e);
				throw new DocumentProcessingException(e);
			}

			documents.add(document);
			
		}
		return documents;
	}
		
	public List<AnnotatedDocument> processAnnotatedDocumentBatch(String inputDirectoryPath, String processedDirectoryPath) throws DocumentProcessingException {
		File inputDirectory = new File(inputDirectoryPath);
		if (!inputDirectory.isDirectory()) {
			throw new DocumentProcessingException("Input directory is not a directory: " + inputDirectoryPath);
		}
		File processedDirectory = new File(processedDirectoryPath);
		if (!processedDirectory.isDirectory()) {
			throw new DocumentProcessingException("Processed directory is not a directory: " + processedDirectoryPath);
		}
		
		List<AnnotatedDocument> annotatedDocuments = new ArrayList<AnnotatedDocument>();
		for(String inputTextFilePath : inputDirectory.list(txtFilter)) {
			File inputTextFile = new File(inputDirectory, inputTextFilePath);
			String annFilePath = inputTextFilePath.substring(0, inputTextFilePath.length()-4)+".ann";
			File annFile = new File(inputDirectory, annFilePath);
			if (!annFile.isFile()) {
				logger.warn("Could not find annotation file for file '" + inputTextFilePath + "', skipping: " + annFile.getAbsolutePath());
				continue;
			}
			String conllxFileName = inputTextFile.getName().substring(0, inputTextFile.getName().length()-4) + ".conllx";
			File conllxFile = new File(processedDirectory, conllxFileName);
			if (!conllxFile.isFile()) {
				logger.warn("Could not find conllx file for file '" + conllxFile.getPath() + "', skipping.");
				continue;
			}
			DocumentAnnotations annotations;
			DocumentInstance document;
			try {
				annotations = annotationReader
						.readAnnotatedDocument(annFile);
				document = dir.readDocumentInstance(inputTextFile, conllxFile);
			} catch (AnnotationReaderException e) {
				logger.error(e);
				throw new DocumentProcessingException(e);
			} catch (IOException e) {
				logger.error(e);
				throw new DocumentProcessingException(e);
			}

			AnnotatedDocument annotatedDocument = new AnnotatedDocument(document, annotations);
			annotatedDocuments.add(annotatedDocument);
			
		}
		return annotatedDocuments;
	}

}
